package cn.iocoder.yudao.module.worker.service.clerklevel;

import cn.iocoder.yudao.module.worker.controller.admin.category.vo.CategoryPageReqVO;
import cn.iocoder.yudao.module.worker.controller.admin.category.vo.CategoryRespVO;
import cn.iocoder.yudao.module.worker.controller.admin.goods.vo.WorkerGoodsPageReqVO;
import cn.iocoder.yudao.module.worker.controller.app.clerklevel.vo.AppClerkLevelPageReqVO;
import cn.iocoder.yudao.module.worker.controller.app.clerklevel.vo.AppClerkLevelSaveReqVO;
import cn.iocoder.yudao.module.worker.dal.dataobject.category.CategoryDO;
import cn.iocoder.yudao.module.worker.dal.dataobject.goods.WorkerGoodsDO;
import cn.iocoder.yudao.module.worker.dal.mysql.category.CategoryMapper;
import cn.iocoder.yudao.module.worker.dal.mysql.goods.WorkerGoodsMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.util.*;
import cn.iocoder.yudao.module.worker.controller.admin.clerklevel.vo.*;
import cn.iocoder.yudao.module.worker.dal.dataobject.clerklevel.ClerkLevelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.worker.dal.mysql.clerklevel.ClerkLevelMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.worker.enums.ErrorCodeConstants.*;

/**
 * 店员等级 Service 实现类
 *
 * @author Jerry
 */
@Service
@Validated
public class ClerkLevelServiceImpl implements ClerkLevelService {

    @Resource
    private ClerkLevelMapper clerkLevelMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private WorkerGoodsMapper workerGoodsMapper;

    @Override
    public Long createClerkLevel(ClerkLevelSaveReqVO createReqVO) {
        // 插入
        ClerkLevelDO clerkLevel = BeanUtils.toBean(createReqVO, ClerkLevelDO.class);
        clerkLevelMapper.insert(clerkLevel);
        // 返回
        return clerkLevel.getId();
    }

    @Override
    public void updateClerkLevel(ClerkLevelSaveReqVO updateReqVO) {
        // 校验存在
        validateClerkLevelExists(updateReqVO.getId());
        // 更新
        ClerkLevelDO updateObj = BeanUtils.toBean(updateReqVO, ClerkLevelDO.class);
        clerkLevelMapper.updateById(updateObj);
    }

    @Override
    public void deleteClerkLevel(Long id) {
        // 校验存在
        validateClerkLevelExists(id);
        // 删除
        clerkLevelMapper.deleteById(id);
    }

    private void validateClerkLevelExists(Long id) {
        if (clerkLevelMapper.selectById(id) == null) {
            throw exception(CLERK_LEVEL_NOT_EXISTS);
        }
    }

    @Override
    public ClerkLevelDO getClerkLevel(Long id) {
        return clerkLevelMapper.selectById(id);
    }

    @Override
    public PageResult<ClerkLevelDO> getClerkLevelPage(ClerkLevelPageReqVO pageReqVO) {
        return clerkLevelMapper.selectPage(pageReqVO);
    }

    @Override
    public Long createClerkLevel(AppClerkLevelSaveReqVO createReqVO) {
        // 插入
        ClerkLevelDO clerkLevel = BeanUtils.toBean(createReqVO, ClerkLevelDO.class);
        clerkLevelMapper.insert(clerkLevel);
        // 返回
        return clerkLevel.getId();
    }

    @Override
    public void updateClerkLevel(AppClerkLevelSaveReqVO updateReqVO) {
        // 校验存在
        validateClerkLevelExists(updateReqVO.getId());
        // 更新
        ClerkLevelDO updateObj = BeanUtils.toBean(updateReqVO, ClerkLevelDO.class);
        clerkLevelMapper.updateById(updateObj);
    }

    @Override
    public PageResult<ClerkLevelDO> getClerkLevelPage(AppClerkLevelPageReqVO pageReqVO) {
        return clerkLevelMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CategoryRespVO> getClerkLevelPrice(Long id) {
        ClerkLevelDO clerkLevelDO = clerkLevelMapper.selectById(id);
        Map<Long,Integer> priceMap = new HashMap<>();
        if(StringUtils.isNotBlank(clerkLevelDO.getGoodsList())){
            priceMap = JSON.parseObject(clerkLevelDO.getGoodsList(), new TypeReference<Map<Long,Integer>>(){});
        }
        // 商品缓存
        WorkerGoodsPageReqVO workerGoodsReqVO = new WorkerGoodsPageReqVO();
        List<WorkerGoodsDO> goodsList = workerGoodsMapper.selectList(workerGoodsReqVO);
        Map<Long, List<WorkerGoodsDO>> cateMap = new HashMap<>();
        Map<Long, List<WorkerGoodsDO>> cateParentMap = new HashMap<>();
        for(WorkerGoodsDO goods : goodsList){
            Integer price = priceMap.get(goods.getId());
            goods.setPrice(price);
            List<WorkerGoodsDO> list = cateMap.get(goods.getCategoryId());
            if(list == null){
               list = new ArrayList<>();
               list.add(goods);
            }else{
               list.add(goods);
            }
            cateMap.put(goods.getCategoryId(), list);

            List<WorkerGoodsDO> parentList = cateParentMap.get(goods.getCategoryParentId());
            if(parentList == null){
               parentList = new ArrayList<>();
               parentList.add(goods);
            }else{
               parentList.add(goods);
            }
            cateParentMap.put(goods.getCategoryParentId(), parentList);
        }

        List<CategoryRespVO> dataList = new ArrayList<>();

        // 分类缓存
        Map<Long, List<CategoryDO>> categoryMap = new HashMap<>();
        CategoryPageReqVO categoryReqVO = new CategoryPageReqVO();
        List<CategoryDO> cateDOList = categoryMapper.selectList(categoryReqVO);
        for(CategoryDO cateDO : cateDOList){
            List<CategoryDO> list = categoryMap.get(cateDO.getParentId());
            if(list == null){
                list = new ArrayList<>();
                list.add(cateDO);
            }else{
                list.add(cateDO);
            }
            categoryMap.put(cateDO.getParentId(), list);
        }

        List<CategoryDO> cateList = categoryMap.get(-1L);
        if(!CollectionUtils.isEmpty(cateList)){
            for(CategoryDO cate : cateList){
                List<WorkerGoodsDO> list = cateMap.get(cate.getId());
                List<WorkerGoodsDO> parentList = cateParentMap.get(cate.getId());
                if(!CollectionUtils.isEmpty(list) || !CollectionUtils.isEmpty(parentList)){
                    CategoryRespVO category = new CategoryRespVO();
                    category.setId(cate.getId());
                    category.setName(cate.getName());
                    // 一级分类
                    if(!CollectionUtils.isEmpty(list)){
                        category.setGoodsList(list);
                    }
                    // 二级分类
                    if(!CollectionUtils.isEmpty(parentList)){
                        category.setRowspan(parentList.size());
                        List<CategoryDO> categoryDOList = categoryMap.get(cate.getId());
                        List<CategoryRespVO> categoryList = new ArrayList<>();
                        for(CategoryDO cateDO : categoryDOList){
                            if(!CollectionUtils.isEmpty(cateMap.get(cateDO.getId()))){
                                CategoryRespVO cateVO = new CategoryRespVO();
                                cateVO.setId(cateDO.getId());
                                cateVO.setName(cateDO.getName());
                                cateVO.setGoodsList(cateMap.get(cateDO.getId()));
                                categoryList.add(cateVO);
                            }
                        }
                        category.setCategoryList(categoryList);
                    }
                    dataList.add(category);
                }
            }
        }
        return dataList;
    }

    @Override
    public void saveClerkLevelPrice(ClerkLevelSaveReqVO updateReqVO) {
        ClerkLevelDO clerkLevelDO = clerkLevelMapper.selectById(updateReqVO.getId());

        List<CategoryRespVO> categoryList = updateReqVO.getCategoryList();
        Map<Long, Integer> priceMap = new HashMap<>();
        for(CategoryRespVO category : categoryList){
            List<WorkerGoodsDO> goodsList = category.getGoodsList();
            // 一级分类
            if(!CollectionUtils.isEmpty(goodsList)){
                for(WorkerGoodsDO goods : goodsList){
                    priceMap.put(goods.getId(), goods.getPrice());
                }
            }

            // 二级分类
            List<CategoryRespVO> cateList = category.getCategoryList();
            if(!CollectionUtils.isEmpty(cateList)){
                for(CategoryRespVO cate : cateList){
                    if(!CollectionUtils.isEmpty(cate.getGoodsList())){
                        for(WorkerGoodsDO goods: cate.getGoodsList()){
                            priceMap.put(goods.getId(), goods.getPrice());
                        }
                    }
                }
            }
        }

        clerkLevelDO.setGoodsList(JSON.toJSONString(priceMap));
        clerkLevelMapper.updateById(clerkLevelDO);
    }

    @Override
    public List<ClerkLevelDO> getClerkLevelList() {
        return clerkLevelMapper.selectList();
    }

    @Override
    public List<ClerkLevelDO> getClerkLevelListByIds(List<Long> ids) {
        return clerkLevelMapper.selectBatchIds(ids);
    }

    @Override
    public void updateClerkLevelStatus(Long id, Boolean status) {
        ClerkLevelDO clerkLevelDO = clerkLevelMapper.selectById(id);
        clerkLevelDO.setStatus(status);
        clerkLevelMapper.updateById(clerkLevelDO);
    }

}